package com.itlong.cloud.intercept;

import com.itlong.cloud.POJO.PO.OperationLogPO;
import com.itlong.cloud.POJO.PO.UserLoginLogPO;
import com.itlong.cloud.POJO.VO.app.AppUserCacheVO;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.enumerate.SystemTypeEnum;
import com.itlong.cloud.noncore.commons.IOperationLogServiceClient;
import com.itlong.cloud.noncore.commons.IUserLoginLogServiceClient;
import com.itlong.cloud.user.app.IAppUserInfoCacheServiceClient;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.regex.Pattern;

/**
 * <desc>
 *      用户操作日志拦截器。
 * </desc>
 *
 * @createDate 2017/11/01
 */
@Aspect
@Component
public class AppLogIntercept {

 // 定义一个切入点
    @Pointcut("execution(* com.itlong.cloud.controller.current.*.*(..))")
    public void excudeService(){}

    @Autowired
    IOperationLogServiceClient iOperationLogServiceClient;

    @Autowired
    IAppUserInfoCacheServiceClient iAppUserInfoCacheServiceClient;

    @Autowired
    IUserLoginLogServiceClient iUserLoginLogServiceClient;

    /**
     * <desc>
     *      用户操作日志证拦截器
     *      注：每个系统的操作日志拦截器需在拦截器中指定SystemType 对应枚举类 SystemTypeEnum
     * </desc>
     *
     * @param thisJoinPoint
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/01
     */
    @After("excudeService() && @annotation(loggerInfo)")
    public void twiceAsOld(JoinPoint thisJoinPoint,LoggerInfo loggerInfo) throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = HttpProtocolUtil.getIpAddr(request);
        //使用正则表达式校验IP的格式是否正确
        String pattern="^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
        boolean isMatch= Pattern.matches(pattern, ip);
        ip = isMatch?ip:"";
        if ("login".equals(loggerInfo.identifer()) || "newLogin".equals(loggerInfo.identifer())){
            UserLoginLogPO userLoginLogPO = (UserLoginLogPO) request.getAttribute("loginUser");
            if (userLoginLogPO != null){
                iUserLoginLogServiceClient.save(userLoginLogPO);
            }
        }else {
            String uri = request.getRequestURI();
            MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
            Method method = signature.getMethod();
            OperationLogPO log = new OperationLogPO();
            String token = request.getParameter("token");
            if (token == null) {
                token = request.getAttribute("token") == null ? "" : request.getAttribute("token").toString();
            }
            //获取登录用户信息
            AppUserCacheVO userInfo = iAppUserInfoCacheServiceClient.retrieve(token);
            if (userInfo != null) {
                //app操作日志账号存储电话，海外用户无电话号存邮箱
                log.setAccount(userInfo.getPhoneNo() == null || "".equals(userInfo.getPhoneNo()) ? userInfo.getEmail() : userInfo.getPhoneNo());
                log.setRealName(userInfo.getUserName());
                log.setIp(ip);
                if (userInfo.getLoginDevice().equals("1")) {
                    log.setSystemType(SystemTypeEnum.ANDROID.getType());
                } else {
                    log.setSystemType(SystemTypeEnum.IOS.getType());
                }
                log.setOperationUse(loggerInfo.operateDesc());
                log.setUrl(uri);
                //保存操作记录
                iOperationLogServiceClient.save(log);
            }
        }
    }

}
